package cn.sxw.ld.module.setmeal.controller;

import cn.sxw.ld.common.dto.R;
import cn.sxw.ld.module.dish.dto.DishDto;
import cn.sxw.ld.module.setmeal.dto.SetmealDishDto;
import cn.sxw.ld.module.setmeal.dto.SetmealDto;
import cn.sxw.ld.module.setmeal.pojo.Setmeal;
import cn.sxw.ld.module.setmeal.pojo.SetmealDish;
import cn.sxw.ld.module.category.service.CategoryService;
import cn.sxw.ld.module.dish.service.DishService;
import cn.sxw.ld.module.setmeal.service.SetmealDishService;
import cn.sxw.ld.module.setmeal.service.SetmealService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName:SetmealController
 * Package:cn.sjxy.graduation.controller
 * Description:
 *
 * @Date:2022/6/10 15:22
 * @Author:SXW
 */
@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishService dishService;

    /**
     * 新增套餐
     * 新增套餐不止操作套餐表，还有维护套餐与菜品关系的表
     *
     * @param setmealDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto) {
        setmealService.saveDishAndSetmealDish(setmealDto);
        return R.success("添加套餐成功！");
    }

    /**
     * 分页查询操作
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        Page setmealDtoPage = setmealService.getPage(page, pageSize, name);
        return R.success(setmealDtoPage);
    }

    /**
     * 删除套餐
     * 无论删除一个或多个，请求地址都是一样的
     * 删除套餐，需要删除套餐表与套餐菜品关联表中的对应数据
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids) {
        setmealService.deleteDishAndSetmealDish(ids);
        return R.success("删除成功！");
    }

    /**
     * 根据传回的 id 修改售卖状态信息
     *
     * @param ids
     * @param status
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> updateStatus(@RequestParam(value = "ids") List<Long> ids, @PathVariable("status") Integer status) {
        setmealService.changeStatus(ids, status);
        return R.success("菜品状态修改成功！");
    }

    /**
     * 根据条件查询套餐
     *
     * @param setmeal
     * @return
     */
    @GetMapping("/list")
    public R<List<Setmeal>> list(Setmeal setmeal) {
        List<Setmeal> setmeals = setmealService.getSetmeals(setmeal);
        return R.success(setmeals);
    }

    /**
     * 查询回显数据
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<SetmealDto> addUi(@PathVariable Long id) {
        SetmealDto setmealDto = setmealService.viewBack(id);
        return R.success(setmealDto);
    }

    /**
     * 修改套餐
     *
     * @param setmealDto
     * @return
     */
    @PutMapping
    @CacheEvict(value = "setmealCache", allEntries = true)
    public R<String> update(@RequestBody SetmealDto setmealDto) {
        // 修改套餐表
        setmealService.updateById(setmealDto);

        /* 修改表中数据，可能操作多个数据，依次修改较为麻烦
         * 1. 直接删除套餐表中套餐 id 对应的所有数据
         * 2. 删除套餐菜品关系表中套餐 id 对应的所有数据
         * 3. 将传回的值做保存
         *
         * 注： 不直接调用删除套餐方法是因为，调用删除套餐方法还需要判断售卖状态
         *      而本处的删除只是为了方便插入数据
         */
        // 1. 删除表中套餐表中记录
        LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealLambdaQueryWrapper.eq(Setmeal::getId, setmealDto.getId());
        setmealService.remove(setmealLambdaQueryWrapper);

        // 2. 删除套餐
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId, setmealDto.getId());
        setmealDishService.remove(setmealDishLambdaQueryWrapper);

        // 3. 保存提交过来的数据
        setmealService.saveDishAndSetmealDish(setmealDto);
        return R.success("修改套餐成功");
    }

    /**
     * 客户端：回显套餐数据和包含的菜品数据
     * 1. 根据传回的套餐id，获取当前套餐信息
     * 2. 根据套餐 id 查套餐菜品关系表（setmeal_dish），获得该套餐关联的所有菜品的集合
     * 3. 处理菜品集合，根据菜品 id 查询菜品口味表，获取菜品详细信息
     *
     * @param setmealId
     * @return
     */
    @GetMapping("/dish/{setmealId}")
    public R<List<SetmealDishDto>> showSetmeal(@PathVariable Long setmealId) {

        // 获取当前套餐下关联的所有菜品
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId, setmealId);
        List<SetmealDish> dishes = setmealDishService.list(setmealDishLambdaQueryWrapper);

        // 页面还需要展示口味，图片信息。需要处理集合
        List<SetmealDishDto> dishList = dishes.stream().map(item -> {
            // 每次遍历都是一个新的转换对象
            SetmealDishDto setmealDishDto = new SetmealDishDto();

            // 将共有属性复制
            BeanUtils.copyProperties(item, setmealDishDto);

            // 获取含有菜品图片，口味信息的菜品口味转换对象
            Long dishId = item.getDishId();
            DishDto dishAndFlavor = dishService.getDishAndFlavor(dishId);

            // 处理特有数据
            setmealDishDto.setImage(dishAndFlavor.getImage());
            setmealDishDto.setFlavors(dishAndFlavor.getFlavors());

            return setmealDishDto;
        }).collect(Collectors.toList());

        return R.success(dishList);

    }
}
